
\section{ Distancias entre etiquetas }

A continuaci\'on de muestra el c\'odigo que hace referencia al proceso de hallar la distancia entre el cursor y cualquier etiqueta de la interfaz:

{\scriptsize
\begin{verbatim}
//Funcion que retorna la distancia minima entre un vertice de la etiqueta y el mouse
  float getMinDist(int offsetx,int offsety,float zoom,float zoomy,float dragX,float dragY) {
    float dista =0;
    switch(tipo) {
    case 1:      
      dista = abs(((((mouseX-dragX)- (width-offsetx)/2))/zoom)-this.x1);
      dista = abs(((((mouseX-dragX)- (width-offsetx)/2))/zoom)-(this.x1+this.ancho))
<dista?abs(((((mouseX-dragX)- (width-offsetx)/2))/zoom)-(this.x1+this.ancho)):dista;
      dista = abs(((((mouseY-dragY)- (height-offsety)/2))/zoomy)-this.y1)
<dista?abs(((((mouseY-dragY)- (height-offsety)/2))/zoomy)-this.y1):dista;
      dista = abs(((((mouseY-dragY)- (height-offsety)/2))/zoomy)-(this.y1+this.alto))
<dista?abs(((((mouseY-dragY)- (height-offsety)/2))/zoomy)-(this.y1+this.alto)):dista;
      return dista;
    case 2:
      int x2 = (int)((((mouseX-dragX) -((width-offsetx)/2)))/zoom);
      int y2 = (int)((((mouseY-dragY) -((height-offsety)/2)))/zoomy);
      int rad = (int)(sqrt(pow((int)(x2-x1),2)+pow((int)(y2-y1),2)));
      return abs(radio-rad);
    case 3:
      Iterator i = puntos.iterator();
      int[] punto = (int[]) i.next();
      int[] punto2 = (int[]) i.next();
      int[] primerPunto = punto;
      float m=0;
      float b=0;
      if(punto[0] - punto2[0] == 0f) {
        //Vertical
        dista = abs((((mouseX-dragX)- (width-offsetx)/2)/zoom)-punto[0]);
      }
      else {
        m = (float)(punto2[1]-punto[1])/(punto2[0]-punto[0]);

        b = (float)punto[1] -1*m*punto[0];
        if(m==0f) {
          //Horizontal
          dista=abs(((((mouseY-dragY)- (height-offsety)/2)/zoomy)-punto[1]));
        }
        else {
          dista = abs((m*((((mouseX-dragX)-(width-offsetx)/2))/zoomy))
-((((mouseY-dragY)-(height-offsety)/2))/zoomy)+b);
          dista /=sqrt(pow(m,2)+1);
        }
      }
      float dista2=100000000;
      while(i.hasNext()) {
        punto = punto2;
        punto2 = (int[]) i.next();
        if(punto[0] - punto2[0] == 0f) {
          //Vertical
          dista2= abs(((((mouseX-dragX)- (width-offsetx)/2))/zoom)-punto[0]);
          dista= dista2<dista?dista2:dista;
        }
        else {
          m =(float) (punto2[1]-punto[1])/(punto2[0]-punto[0]);
          b = (float)punto[1] -1*m*punto[0];
          if(m==0f) {
            //Horizontal
            dista2=abs(((((mouseY-dragY)- (height-offsety)/2))/zoomy)-punto[1]);
            dista= dista2<dista?dista2:dista;
          }
          else {
            dista2 = abs((m*((((mouseX-dragX)-(width-offsetx)/2))/zoom))
-((((mouseY-dragY)-(height-offsety)/2))/zoomy)+b);
            dista2 /=sqrt(pow(m,2)+1);
            dista= dista2<dista?dista2:dista;
          }
        }
      }
      punto = primerPunto;
      if(punto[0] - punto2[0] == 0f) {
        //Vertical
        dista2= abs(((((mouseX-dragX)- (width-offsetx)/2))/zoom)-punto[0]);
        dista= dista2<dista?dista2:dista;
      }
      else {
        m =(float) (punto2[1]-punto[1])/(punto2[0]-punto[0]);
        b = (float)punto[1] -1*m*punto[0];
        if(m==0f) {
          //Horizontal
          dista2=abs(((((mouseY-dragY)- (height-offsety)/2))/zoomy)-punto[1]);
          dista= dista2<dista?dista2:dista;
        }
        else {
          dista2 = abs((m*((((mouseX-dragX)-(width-offsetx)/2))/zoom))
-((((mouseY-dragY)-(height-offsety)/2))/zoomy+b));
          dista2 /=sqrt(pow(m,2)+1);
          dista= dista2<dista?dista2:dista;
        }
      }
      return dista;
    case 4:
      return sqrt(pow(((((mouseX-dragX)-(width-offsetx)/2))/zoom)-x1,2)
+pow(((((mouseY-dragY)-(height-offsety)/2))/zoomy)-y1,2));      
      case 5:      
      i = puntos.iterator();
      int[] p = (int[])i.next();
      float dist = sqrt(pow(((((mouseX-dragX)-(width-offsetx)/2))/zoom)-p[0],2)
+pow(((((mouseY-dragY)-(height-offsety)/2))/zoomy)-p[1],2));      
      while(i.hasNext()){
       p=(int[])i.next();
       float distmp =  sqrt(pow(((((mouseX-dragX)-(width-offsetx)/2))/zoom)-p[0],2)
+pow(((((mouseY-dragY)-(height-offsety)/2))/zoomy)-p[1],2));
       dist = distmp < dist? distmp:dist;
      }
      return dist;      
    }    
    return 10000;
  }
\end{verbatim}}

\pagebreak

\section{Colision de un hueso con una camilla}

A continuaci\'on se muestra el c\'odigo que detecta y resuelve cualquier colisi\'on con el entorno:

{\scriptsize
\begin{verbatim}

public void colisionStickCamilla(){
  PVector vo = new PVector(width/2,height,0);
  
  for(int i = 0;i<constraints.size();i++){
   Stick st = (Stick) constraints.get(i);
  
   Sphere s1 = st.gets1();
   Sphere s2 = st.gets2();
   //Particle's psoitions
   PVector v1 = s1.getVector();
   PVector v2 = s2.getVector();
   PVector vold1 = s1.getPosicionAnterior();
   PVector vold2 = s2.getPosicionAnterior();
   
   if(inBox(v1)){
     //println("V1 dentro");
     PVector proj = v1.get();
     proj.y = height+50;
     float d = proj.dist(v1);
     PVector mov = vold1.get();
     mov.sub(v1);
     mov.normalize();
     mov.mult(d);
     v1.add(mov);
     
   }
   else if(inBox(v2)){
    // println("v2 dentro");
     PVector proj = v2.get();
     proj.y = height+50;
     //proj.x = abs(width/2-100 - proj.x) > abs(width/2+100 - proj.x) ? width/2+100:width/2-100; 
     float d = proj.dist(v2);
     PVector mov = vold2.get();
     mov.sub(v2);
     mov.normalize();
     mov.mult(d);
     v2.add(mov);
     
   }
   
   else{
    //Palo diagonal 
     PVector interX = interseccionPlano(new PVector(width/2,height+50,0),new PVector(0,-1,0),v1,v2);
     if(interX.x > width/2-50 && interX.x < width/2+50){
      
       PVector interYizq = interseccionPlano(new PVector(width/2-50,height+150,0),new PVector(-1,0,0),v1,v2);
       PVector interYder = interseccionPlano(new PVector(width/2+50,height+150,0),new PVector(1,0,0),v1,v2);
       
       if(interYizq.y > height+50 && interYizq.y < height+150){
        println("diagonal izquierda");
        PVector medio = interX.get();
        medio.add(interYizq);
        medio.div(2);
        PVector proj = medio.get();
        proj.x=width/2-50;
        proj.y=height+50;
        float distancia = medio.dist(proj);
        PVector mov = proj.get();
        mov.sub(medio);
        mov.normalize();
        
        float dist1 = v1.dist(medio);
        float dist2 = v2.dist(medio);
        float total = v1.dist(v2);
        dist1=dist1/total;
        dist2=dist2/total;
        PVector mov1 = mov.get();
        mov1.mult(distancia);
        mov1.mult(dist1);
        PVector mov2 = mov.get();
        mov2.mult(distancia);
        mov2.mult(dist2);
        v1.add(mov1);
        v2.add(mov2);
       }
       else if(interYder.y > height+50 && interYder.y < height+150){
         println("diagonal derecha");
        PVector medio = interX.get();
        medio.add(interYder);
        medio.div(2);
        PVector proj = medio.get();
        proj.x=width/2+50;
        proj.y=height+50;
        float distancia = medio.dist(proj);
        PVector mov = proj.get();
        mov.sub(medio);
        mov.normalize();
        
        float dist1 = v1.dist(medio);
        float dist2 = v2.dist(medio);
        float total = v1.dist(v2);
        dist1=dist1/total;
        dist2=dist2/total;
        PVector mov1 = mov.get();
        mov1.mult(distancia);
        mov1.mult(dist1);
        PVector mov2 = mov.get();
        mov2.mult(distancia);
        mov2.mult(dist2);
        v1.add(mov1);
        v2.add(mov2); 
       }
     }
     
     
   }
   
  }
  
  
}

\end{verbatim}}